
#pragma once

#include "atr/core/boolean.hpp"

namespace atr {
namespace core {
namespace __core {

template <typename Boolean, typename True_Type>		struct _else
{
	/** Value for 'else' case */
	template <typename False_Type>
	struct _
	{
		/** Output type of whole if-else */
		using type = True_Type;
	};
};

template <typename True_Type>
struct _else<_false, True_Type>
{
	/** Value for 'else' case */
	template <typename False_Type>
	struct _
	{
		/** Output type of whole if-else */
		using type = False_Type;
	};
};

template <typename First_Boolean, typename First_Type, typename Boolean>
													struct _else_if
{
	template <typename Type>
	struct _
	{
		/** Partial specialization for 'else if' keyword */
		template <typename Next_Boolean>
		using _else_if = __core::_else_if<_true, First_Type, Next_Boolean>;
		/** Specialization for 'else' keyword */
		using _else = __core::_else<_true, First_Type>;
	};
};

template <typename First_Type, typename Boolean>
struct _else_if<_false, First_Type, Boolean>
{
	template <typename Type>
	struct _
	{
		/** Partial specialization for 'else if' keyword */
		template <typename Next_Boolean>
		using _else_if = __core::_else_if<Boolean, Type, Next_Boolean>;
		/** Specialization for 'else' keyword */
		using _else = __core::_else<Boolean, Type>;
	};
};

} // namespace __core

template <typename Boolean>				struct _if
{
	/**
	 * @brief   Metaprgoramint class for type specialization.
	 * @details In if<> statement we provide boolean to evaluate, here we
	 *          provide type for it.
	 *
	 * @tparam Type to be returned if if<val> is true
	 */
	template <typename Type>
	struct _
	{
		/** Partial specialization for 'else if' keyword */
		template <typename Next_Boolean>
		using _else_if = __core::_else_if<Boolean, Type, Next_Boolean>;

		/** Specialization for 'else' keyword */
		using _else    = __core::_else<Boolean, Type>;
	};
};


} // namespace core
} // namespace atr